#include "controller.h"
#include <QFile>
#include <QDebug>
#include <QDomDocument>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QStringList>
#include <QUrl>

Controller::Controller()
{
    clear();
}

void Controller::clear()
{
    mId = 0;
    mIsHeating = false;
    mName.clear();
    mBoards.clear();
}

bool Controller::loadController(const QString fileName, const int cid, const bool isHeating)
{
    clear();
    QDomDocument domDocument;

    QFile file(fileName);
    if (!file.open(QIODevice::ReadOnly)) {
        return false;
    }
    if (!domDocument.setContent(&file)) {
        file.close();
        return false;
    }
    file.close();

    qDebug();

    QDomElement elemControl = domDocument.documentElement();
    if (0 != elemControl.tagName().compare("Controller", Qt::CaseInsensitive)) {
        qDebug() << elemControl.tagName();
        return false;
    }
    qDebug() << "Controller version : " << elemControl.attribute("version");
    elemControl.clear();

    QDomNodeList nodeList = domDocument.documentElement().elementsByTagName("Control");
    for (int i=0; i<nodeList.count(); i++) {
        elemControl = nodeList.at(i).toElement();
        qDebug() << "Control cid : " << elemControl.attribute("cid");
        if (cid == elemControl.attribute("cid").toInt()) {
            break;
        }
        elemControl.clear();
    }
    if (true == elemControl.isNull()) {
        return false;
    }

    mId = cid;
    mIsHeating = isHeating;

    QDomNode node = elemControl.firstChild();
    while (false == node.isNull()) {
        QDomElement elem = node.toElement();
        qDebug() << "  " << qPrintable(elem.tagName()) << "," << qPrintable(elem.text());

        if (0 == elem.tagName().compare("cname", Qt::CaseInsensitive)) {
            mName = elem.text();
        } else if (0 == elem.tagName().compare("Board", Qt::CaseInsensitive)) {
            Board board;
            parseBoard(elem.firstChild(), board);
            mBoards.append(board);
        }

        node = node.nextSibling();
    }
    qDebug() << "  " << "mBoards.count()" << mBoards.count();

    qDebug();

    nodeList = domDocument.documentElement().elementsByTagName("Sms");
    if (1 <= nodeList.count()) {
        elemControl = nodeList.at(0).toElement();
        node = elemControl.firstChild();

        while (false == node.isNull()) {
            QDomElement elem = node.toElement();
            qDebug() << "  " << qPrintable(elem.tagName()) << "," << qPrintable(elem.text());

            if (0 == elem.tagName().compare("url", Qt::CaseInsensitive)) {
                mSmsUrl = elem.text();
            } else if (0 == elem.tagName().compare("from", Qt::CaseInsensitive)) {
                mSmsFrom = elem.text();
            } else if (0 == elem.tagName().compare("tos", Qt::CaseInsensitive)) {
                mSmsTos = elem.text();
            }

            node = node.nextSibling();
        }
    }

    return true;
}

bool Controller::loadAction(const QString fileName)
{
    QString xmlFile = "";

    QFile file(fileName);
    if (!file.open(QIODevice::ReadOnly)) {
        return false;
    }
    QTextStream stream(&file);
    xmlFile = stream.readAll();
    file.close();

    return mAction.load(xmlFile);
}

bool Controller::loadSunLight(const QString fileName)
{
    return mSunLight.load(fileName);
}

int Controller::boardType(int bid)
{
    for (int b=0; b<mBoards.size(); b++) {
        if (mBoards[b].mId == bid) {
            return mBoards[b].mType;
        }
    }

    return BOARD_TYPE_UNKNOWN;
}

void Controller::setRelayStatus(int bid, int rid, int status, QObject *timer, int timerDelay)
{
    for (int b=0; b<mBoards.size(); b++) {
        if (mBoards[b].mId == bid) {
            for (int r=0; r<mBoards[b].mRelays.size(); r++) {
                if (mBoards[b].mRelays[r].mId == rid) {
                    mBoards[b].mRelays[r].mStatus = status;

                    if (timer) {
                        if (mBoards[b].mRelays[r].mTimerId) {
                            timer->killTimer(mBoards[b].mRelays[r].mTimerId);
                            qDebug() << "---" << "mTimerId" << mBoards[b].mRelays[r].mTimerId;
                            mBoards[b].mRelays[r].mTimerId = 0;
                        }

                        int delay = 0;
                        if (-1 < timerDelay) {
                            delay = timerDelay;
                        } else {
                            switch (status) {
                            case RELAY_STATUS_OFF:
                                if (0 <= mBoards[b].mRelays[r].mIdRelay) {
                                    delay = mBoards[b].mRelays[r].mDelayAction;
                                }
                                break;
                            case RELAY_STATUS_ON:
                            case RELAY_STATUS_AIR:
                            case RELAY_STATUS_COOLING:
                            case RELAY_STATUS_HEATING:
                                delay = mBoards[b].mRelays[r].mDelayAction;
                                break;
                            }
                        }
                        if (delay) {
                            mBoards[b].mRelays[r].mTimerId = timer->startTimer(delay*1000);
                            qDebug() << "+++" << "mTimerId" << mBoards[b].mRelays[r].mTimerId;
                        }
                    }
                    break;
                }
            }
            break;
        }
    }
}

Relay *Controller::relay(int bid, int rid)
{
    for (int b=0; b<mBoards.size(); b++) {
        if (mBoards[b].mId == bid) {
            for (int r=0; r<mBoards[b].mRelays.size(); r++) {
                if (mBoards[b].mRelays[r].mId == rid) {
                    return &mBoards[b].mRelays[r];
                }
            }
        }
    }

    return NULL;
}

Relay *Controller::timerRelay(int timerId, int *bid)
{
    for (int b=0; b<mBoards.size(); b++) {
        for (int r=0; r<mBoards[b].mRelays.size(); r++) {
            if(timerId == mBoards[b].mRelays[r].mTimerId) {
                if (bid) {
                    *bid = mBoards[b].mId;
                }
                return &mBoards[b].mRelays[r];
            }
        }
    }

    return NULL;
}

int Controller::currentStatus(Relay *pRelay)
{
    int status = RELAY_STATUS_UNKNOWN;
    if (0 <= pRelay->mIdRemote) {
        int bid = (pRelay->mIdRemote/100);
        int rid = (pRelay->mIdRemote%100);
        int current = pRelay->mCurrent;

        for (int b=0; b<mBoards.size(); b++) {
            if (mBoards[b].mId == bid) {
                for (int r=0; r<mBoards[b].mRelays.size(); r++) {
                    if (mBoards[b].mRelays[r].mId == rid) {
                        if (mBoards[b].mRelays[r].mRemoteCoolingMin <= current) {
                            status = mIsHeating ? RELAY_STATUS_HEATING : RELAY_STATUS_COOLING;
                        } else if (mBoards[b].mRelays[r].mRemoteAirMin <= current) {
                            if (pRelay->mFlagRemote) {
                                status = mIsHeating ? RELAY_STATUS_HEATING : RELAY_STATUS_COOLING;
                            } else {
                                status = RELAY_STATUS_AIR;
                            }
                        } else {
                            status = RELAY_STATUS_ON;
                        }
                        break;
                    }
                }
                break;
            }
        }
    }

    return status;
}

QString Controller::packetTcpConnect() const
{
    // $connect:cid,cname,[bid,name,<rid,name,notUsed,type,status>,<...>,],[...],$
    QString packet("$connect:");
    packet += QString("%1,%2,").arg(mId).arg(mName);

    for (int b=0; b<mBoards.size(); b++) {
        packet += "[";
        packet += QString("%1,").arg(mBoards[b].mId);
        packet += QString("%1,").arg(mBoards[b].mName);
        for (int r=0; r<mBoards[b].mRelays.size(); r++) {
            if (0x10 <= mBoards[b].mRelays[r].mId) {
                continue;
            }
            packet += "<";
            packet += QString("%1,").arg(mBoards[b].mRelays[r].mId);
            packet += QString("%1,").arg(mBoards[b].mRelays[r].mName);
            packet += QString("%1,").arg(mBoards[b].mRelays[r].mNotUsed);
            if (0 <= mBoards[b].mRelays[r].mIdRemote) {
                int temp = 1 + (10 * (mIsHeating ? 1 : 0)) + (100 * mBoards[b].mRelays[r].mFlagRemote);
                packet += QString("%1,").arg(temp);
            } else {
                packet += "0,";
            }
            packet += QString("%1,").arg(mBoards[b].mRelays[r].mStatus);
            packet += ">,";
        }
        packet += "],";
    }
    packet += "$";

    return packet;
}

QString Controller::packetTcpUpdate(int bid, int rid) const
{
    int status = -1;
    for (int b=0; b<mBoards.size(); b++) {
        if (mBoards[b].mId == bid) {
            for (int r=0; r<mBoards[b].mRelays.size(); r++) {
                if (mBoards[b].mRelays[r].mId == rid) {
                    status = mBoards[b].mRelays[r].mStatus;
                    break;
                }
            }
            break;
        }
    }

    // $update:[cid,bid,rid,status,],$
    QString packet("$update:");
    if (-1 < status) {
        packet += QString("[%1,%2,%3,%4,],").arg(mId).arg(bid).arg(rid).arg(status);
    }
    packet += "$";

    return packet;
}

QString Controller::packetTcpReboot() const
{
    // $reboot:,$
    QString packet("$reboot:,$");

    return packet;
}

void Controller::packetBoardInit(QList<PacketData>& packets)
{
    PacketData packetData;
    uchar bCheckSum;

    for (int b=0; b<mBoards.size(); b++) {
        packetData.sendCount = 0;
        packetData.dataBuf.clear();

        packetData.dataBuf.push_back(PACKET_STARTEND);
        packetData.dataBuf.push_back(PACKET_MIN_LEN + 2);   // numRelay, type
        packetData.dataBuf.push_back((char)PACKET_CMD_BDINIT);
        packetData.dataBuf.push_back(mBoards[b].mId);
        packetData.dataBuf.push_back(mBoards[b].mRelays.size());
        packetData.dataBuf.push_back(mBoards[b].mType);
        bCheckSum = 0;
        for (int c=1; c<packetData.dataBuf.size(); c++) {
            bCheckSum += packetData.dataBuf[c];
        }
        packetData.dataBuf.push_back(bCheckSum);
        packetData.dataBuf.push_back(PACKET_STARTEND);

        packetData.boardSync = 0;
        packets.append(packetData);

        for (int r=0; r<mBoards[b].mRelays.size(); r++) {
            packetData.sendCount = 0;
            packetData.dataBuf.clear();

            packetData.dataBuf.push_back(PACKET_STARTEND);
            if (BOARD_TYPE_REMOTE == mBoards[b].mType) {
                packetData.dataBuf.push_back(PACKET_MIN_LEN + 2);   // rid, vendor
                packetData.dataBuf.push_back(PACKET_CMD_REMOTEINIT);
                packetData.dataBuf.push_back(mBoards[b].mId);
                packetData.dataBuf.push_back(mBoards[b].mRelays[r].mId);
                packetData.dataBuf.push_back(mBoards[b].mRelays[r].mRemoteVendor);
            } else {
                // Board::typeNormal or Board::typeClose
                if (mBoards[b].mRelays[r].mNotUsed) {
                    packetData.dataBuf.push_back(PACKET_MIN_LEN + 2);   // rid, status
                    packetData.dataBuf.push_back(PACKET_CMD_SET);
                    packetData.dataBuf.push_back(mBoards[b].mId);
                    packetData.dataBuf.push_back(mBoards[b].mRelays[r].mId);
                    packetData.dataBuf.push_back(RELAY_STATUS_NOTUSED);
                } else {
                    packetData.dataBuf.push_back(PACKET_MIN_LEN + 1);   // rid
                    packetData.dataBuf.push_back(PACKET_CMD_GET);
                    packetData.dataBuf.push_back(mBoards[b].mId);
                    packetData.dataBuf.push_back(mBoards[b].mRelays[r].mId);
                }
            }
            bCheckSum = 0;
            for (int c=1; c<packetData.dataBuf.size(); c++) {
                bCheckSum += packetData.dataBuf[c];
            }
            packetData.dataBuf.push_back(bCheckSum);
            packetData.dataBuf.push_back(PACKET_STARTEND);

            packetData.boardSync = 0;
            packets.append(packetData);
        }
    }
}

void Controller::packetBoardSync(QList<PacketData>& packets, int bid)
{
    if (-1 < bid) {
        int bIdx = -1;
        for (int b=0; b<mBoards.size(); b++) {
            if (mBoards[b].mId == bid) {
                bIdx = b;
                break;
            }
        }
        if (-1 < bIdx) {
            for (int r=0; r<mBoards[bIdx].mRelays.size(); r++) {
                if (mBoards[bIdx].mRelays[r].mNotUsed) {
                    packetRelaySet(packets, mBoards[bIdx].mId, mBoards[bIdx].mRelays[r].mId, RELAY_STATUS_NOTUSED);
                } else {
                    packetRelaySet(packets, mBoards[bIdx].mId, mBoards[bIdx].mRelays[r].mId, mBoards[bIdx].mRelays[r].mStatus);
                }
            }
        }
    } else {
        for (int b=0; b<mBoards.size(); b++) {
            for (int r=0; r<mBoards[b].mRelays.size(); r++) {
                if (mBoards[b].mRelays[r].mNotUsed) {
                    packetRelaySet(packets, mBoards[b].mId, mBoards[b].mRelays[r].mId, RELAY_STATUS_NOTUSED);
                } else {
                    packetRelaySet(packets, mBoards[b].mId, mBoards[b].mRelays[r].mId, mBoards[b].mRelays[r].mStatus);
                }
            }
        }
    }
}

void Controller::packetRelaySet(QList<PacketData>& packets, int bid, int rid, int status, int timerAction)
{
    bool isFind = false;
    for (int b=0; b<mBoards.size(); b++) {
        if (mBoards[b].mId == bid) {
            for (int r=0; r<mBoards[b].mRelays.size(); r++) {
                if (mBoards[b].mRelays[r].mId == rid) {
                    isFind = true;
                    break;
                }
            }
            break;
        }
    }
    if (isFind) {
        PacketData packetData;
        uchar bCheckSum;

        packetData.sendCount = 0;
        packetData.dataBuf.push_back(PACKET_STARTEND);
        packetData.dataBuf.push_back(PACKET_MIN_LEN + 2);   // rid, status
        packetData.dataBuf.push_back(PACKET_CMD_SET);
        packetData.dataBuf.push_back(bid);
        packetData.dataBuf.push_back(rid);
        packetData.dataBuf.push_back(status);
        bCheckSum = 0;
        for (int c=1; c<packetData.dataBuf.size(); c++) {
            bCheckSum += packetData.dataBuf[c];
        }
        packetData.dataBuf.push_back(bCheckSum);
        packetData.dataBuf.push_back(PACKET_STARTEND);

        packetData.boardSync = 0;
        packetData.timerAction = timerAction;
        if (packets.count()) {
            //packets.prepend(packetData);
            for (int i=0; i<packets.count(); i++) {
                if (0 == packets[i].sendCount) {
                    packets.insert(i, packetData);
                    break;
                }
            }
        } else {
            packets.append(packetData);
        }
    }
}

void Controller::packetRelayGet(QList<PacketData>& packets, int bid, int rid, int boardSync)
{
    bool isFind = false;
    for (int b=0; b<mBoards.size(); b++) {
        if (mBoards[b].mId == bid) {
            for (int r=0; r<mBoards[b].mRelays.size(); r++) {
                if (mBoards[b].mRelays[r].mId == rid) {
                    isFind = true;
                    break;
                }
            }
            break;
        }
    }
    if (isFind) {
        PacketData packetData;
        uchar bCheckSum;

        packetData.sendCount = 0;
        packetData.dataBuf.push_back(PACKET_STARTEND);
        packetData.dataBuf.push_back(PACKET_MIN_LEN + 1);   // rid
        packetData.dataBuf.push_back(PACKET_CMD_GET);
        packetData.dataBuf.push_back(bid);
        packetData.dataBuf.push_back(rid);
        bCheckSum = 0;
        for (int c=1; c<packetData.dataBuf.size(); c++) {
            bCheckSum += packetData.dataBuf[c];
        }
        packetData.dataBuf.push_back(bCheckSum);
        packetData.dataBuf.push_back(PACKET_STARTEND);

        QString strPacket(packetData.dataBuf.toHex());
        for (int i=0; i<packets.size(); i++) {
            if (0 == strPacket.compare(packets.at(i).dataBuf.toHex())) {
                packets[i].sendCount = 0;
                packets[i].boardSync = boardSync;
                return;
            }
        }

        packetData.boardSync = boardSync;
        packets.append(packetData);
    }
}

void Controller::packetRelayCurrent(QList<PacketData>& packets, int bid, int rid)
{
    bool isFind = false;
    for (int b=0; b<mBoards.size(); b++) {
        if (mBoards[b].mId == bid) {
            for (int r=0; r<mBoards[b].mRelays.size(); r++) {
                if (mBoards[b].mRelays[r].mId == rid) {
                    isFind = true;
                    break;
                }
            }
            break;
        }
    }
    if (isFind) {
        PacketData packetData;
        uchar bCheckSum;

        packetData.sendCount = 0;
        packetData.dataBuf.push_back(PACKET_STARTEND);
        packetData.dataBuf.push_back(PACKET_MIN_LEN + 1);   // rid
        packetData.dataBuf.push_back(PACKET_CMD_CURRENT);
        packetData.dataBuf.push_back(bid);
        packetData.dataBuf.push_back(rid);
        bCheckSum = 0;
        for (int c=1; c<packetData.dataBuf.size(); c++) {
            bCheckSum += packetData.dataBuf[c];
        }
        packetData.dataBuf.push_back(bCheckSum);
        packetData.dataBuf.push_back(PACKET_STARTEND);

        QString strPacket(packetData.dataBuf.toHex());
        for (int i=0; i<packets.size(); i++) {
            if (0 == strPacket.compare(packets.at(i).dataBuf.toHex())) {
                packets[i].sendCount = 0;
                packets[i].boardSync = 0;
                return;
            }
        }

        packetData.boardSync = 0;
        if (packets.count()) {
            //packets.prepend(packetData);
            for (int i=0; i<packets.count(); i++) {
                if (0 == packets[i].sendCount) {
                    packets.insert(i, packetData);
                    break;
                }
            }
        } else {
            packets.append(packetData);
        }
    }
}

void Controller::temperatureSet(QList<PacketData>& packets, short set)
{
    PacketData packetData;
    QString strValue;
    strValue.sprintf("%04X", set);

    packetData.sendCount = 0;
    // <STX>01DWS,01,0301<CR><LF>
    packetData.dataBuf.push_back(TEMPERATURE_START);
    packetData.dataBuf.push_back('0');
    packetData.dataBuf.push_back('1');
    packetData.dataBuf.push_back('D');
    packetData.dataBuf.push_back('W');
    packetData.dataBuf.push_back('S');
    packetData.dataBuf.push_back(',');
    packetData.dataBuf.push_back('0');
    packetData.dataBuf.push_back('1');
    packetData.dataBuf.push_back(',');
    packetData.dataBuf.push_back('0');
    packetData.dataBuf.push_back('3');
    packetData.dataBuf.push_back('0');
    packetData.dataBuf.push_back('1');
    packetData.dataBuf.push_back(',');
    packetData.dataBuf.push_back(strValue.at(0).toAscii());
    packetData.dataBuf.push_back(strValue.at(1).toAscii());
    packetData.dataBuf.push_back(strValue.at(2).toAscii());
    packetData.dataBuf.push_back(strValue.at(3).toAscii());
    packetData.dataBuf.push_back(TEMPERATURE_CR);
    packetData.dataBuf.push_back(TEMPERATURE_LF);

    packetData.boardSync = 0;
    packets.append(packetData);
}

void Controller::temperatureGet(QList<PacketData>& packets)
{
    PacketData packetData;

    packetData.sendCount = 0;
    // <STX>01DRS,02,0001<CR><LF>
    packetData.dataBuf.push_back(TEMPERATURE_START);
    packetData.dataBuf.push_back('0');
    packetData.dataBuf.push_back('1');
    packetData.dataBuf.push_back('D');
    packetData.dataBuf.push_back('R');
    packetData.dataBuf.push_back('S');
    packetData.dataBuf.push_back(',');
    packetData.dataBuf.push_back('0');
    packetData.dataBuf.push_back('2');
    packetData.dataBuf.push_back(',');
    packetData.dataBuf.push_back('0');
    packetData.dataBuf.push_back('0');
    packetData.dataBuf.push_back('0');
    packetData.dataBuf.push_back('1');
    packetData.dataBuf.push_back(TEMPERATURE_CR);
    packetData.dataBuf.push_back(TEMPERATURE_LF);

    packetData.boardSync = 0;
    packets.append(packetData);
}

void Controller::sendSms(int bid, int rid)
{
    if (mSmsUrl.isEmpty() || mSmsFrom.isEmpty() || mSmsTos.isEmpty()) {
        return;
    }

    Relay *pRelay = relay(bid, rid);
    QString strTxt;

    if (RELAY_STATUS_OFF == pRelay->mStatus) {
        if (0x1 == (0x1 & pRelay->mSmsFlag)) {
            strTxt = QString("[%1]이(가) [OFF] 되었습니다.").arg(pRelay->mName);
        }
    } else if (RELAY_STATUS_ON == pRelay->mStatus) {
        if (0x2 == (0x2 & pRelay->mSmsFlag)) {
            strTxt = QString("[%1]이(가) [ON] 되었습니다.").arg(pRelay->mName);
        }
    }

    if (strTxt.length()) {
        QString strMsg = QString::fromUtf8(strTxt.toStdString().c_str());

        QNetworkAccessManager *manager = new QNetworkAccessManager();
        QUrl url(mSmsUrl);
        QNetworkRequest request(url);
        request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
        QUrl params;
        params.addQueryItem("sms_from", mSmsFrom);
        params.addQueryItem("sms_to", mSmsTos);
        params.addQueryItem("type_set", "B");
        params.addQueryItem("sms_msg", strMsg);

        //QObject::connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(onReplyFinished(QNetworkReply *)));
        QNetworkReply *reply = manager->post(request, params.encodedQuery());
        Q_UNUSED(reply);
    }
}

void Controller::sendSms2(int bid, int rid, int status)
{
    if (mSmsUrl.isEmpty() || mSmsFrom.isEmpty() || mSmsTos.isEmpty()) {
        return;
    }

    Relay *pRelay = relay(bid, rid);
    QString strTxt;

    if (RELAY_STATUS_OFF == status) {
        if (pRelay->mSmsOff.length()) {
            strTxt = pRelay->mSmsOff;
        }
    } else if (RELAY_STATUS_ON == status) {
        if (pRelay->mSmsOn.length()) {
            strTxt = pRelay->mSmsOn;
        }
    }

    qDebug() << "sendSms2" << bid << rid << status << strTxt;
    if (strTxt.length()) {
        QString strMsg = QString::fromUtf8(strTxt.toStdString().c_str());

        QNetworkAccessManager *manager = new QNetworkAccessManager();
        QUrl url(mSmsUrl);
        QNetworkRequest request(url);
        request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
        QUrl params;
        params.addQueryItem("sms_from", mSmsFrom);
        params.addQueryItem("sms_to", mSmsTos);
        params.addQueryItem("type_set", "B");
        params.addQueryItem("sms_msg", strMsg);

        //QObject::connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(onReplyFinished(QNetworkReply *)));
        QNetworkReply *reply = manager->post(request, params.encodedQuery());
        Q_UNUSED(reply);
    }
}

void Controller::parseBoard(QDomNode node, Board& board)
{
    while (false == node.isNull()) {
        QDomElement elem = node.toElement();

        if (0 == elem.tagName().compare("bid", Qt::CaseInsensitive)) {
            board.mId = elem.text().toInt();
            qDebug() << "  " << qPrintable(elem.tagName()) << board.mId;
        } else if (0 == elem.tagName().compare("bname", Qt::CaseInsensitive)) {
            board.mName = elem.text();
            qDebug() << "  " << qPrintable(elem.tagName()) << board.mName;
        } else if (0 == elem.tagName().compare("btype", Qt::CaseInsensitive)) {
            board.mType = elem.text().toInt();
            qDebug() << "  " << qPrintable(elem.tagName()) << board.mType;
        } else if (0 == elem.tagName().compare("Relay", Qt::CaseInsensitive)) {
            parseRelay(elem.firstChild(), board);
        }

        node = node.nextSibling();
    }
}

void Controller::parseRelay(QDomNode node, Board& board)
{
    Relay relay;

    while (false == node.isNull()) {
        QDomElement elemRelay = node.toElement();

        if (0 == elemRelay.tagName().compare("rid", Qt::CaseInsensitive)) {
            relay.mId = elemRelay.text().toInt();
            qDebug() << "    " << qPrintable(elemRelay.tagName()) << relay.mId;
        } else if (0 == elemRelay.tagName().compare("rname", Qt::CaseInsensitive)) {
            relay.mName = elemRelay.text();
            qDebug() << "    " << qPrintable(elemRelay.tagName()) << relay.mName;
        } else if (0 == elemRelay.tagName().compare("notUsed", Qt::CaseInsensitive)) {
            relay.mNotUsed = elemRelay.text().toInt();
            qDebug() << "    " << qPrintable(elemRelay.tagName()) << relay.mNotUsed;
        } else if (0 == elemRelay.tagName().compare("delayAction", Qt::CaseInsensitive)) {
            relay.mDelayAction = elemRelay.text().toInt();
            qDebug() << "    " << qPrintable(elemRelay.tagName()) << relay.mDelayAction;
        } else if (0 == elemRelay.tagName().compare("idRemote", Qt::CaseInsensitive)) { // for relay board
            relay.mIdRemote = elemRelay.text().toInt();
            qDebug() << "    " << qPrintable(elemRelay.tagName()) << relay.mIdRemote;
        } else if (0 == elemRelay.tagName().compare("idRelay", Qt::CaseInsensitive)) {  // for remote board
            relay.mIdRelay = elemRelay.text().toInt();
            qDebug() << "    " << qPrintable(elemRelay.tagName()) << relay.mIdRelay;
        } else if (0 == elemRelay.tagName().compare("remoteVendor", Qt::CaseInsensitive)) { // for remote board
            relay.mRemoteVendor = elemRelay.text().toInt();
            qDebug() << "    " << qPrintable(elemRelay.tagName()) << relay.mRemoteVendor;
        } else if (0 == elemRelay.tagName().compare("remoteRangeAir", Qt::CaseInsensitive)) {   // for remote board
            QStringList ranges = elemRelay.text().split("-", QString::SkipEmptyParts);
            if (2 == ranges.size()) {
                relay.mRemoteAirMin = ranges[0].toInt();
                relay.mRemoteAirMax = ranges[1].toInt();
                qDebug() << "    " << qPrintable(elemRelay.tagName()) << relay.mRemoteAirMin << relay.mRemoteAirMax;
            }
        } else if (0 == elemRelay.tagName().compare("remoteRangeCooling", Qt::CaseInsensitive)) {   // for remote board
            QStringList ranges = elemRelay.text().split("-", QString::SkipEmptyParts);
            if (2 == ranges.size()) {
                relay.mRemoteCoolingMin = ranges[0].toInt();
                relay.mRemoteCoolingMax = ranges[1].toInt();
                qDebug() << "    " << qPrintable(elemRelay.tagName()) << relay.mRemoteCoolingMin << relay.mRemoteCoolingMax;
            }
        } else if (0 == elemRelay.tagName().compare("smsFlag", Qt::CaseInsensitive)) {  // for relay board
            relay.mSmsFlag = elemRelay.text().toInt();
            qDebug() << "    " << qPrintable(elemRelay.tagName()) << relay.mSmsFlag;
        } else if (0 == elemRelay.tagName().compare("flagRemote", Qt::CaseInsensitive)) {   // for relay board
            relay.mFlagRemote = elemRelay.text().toInt();
            qDebug() << "    " << qPrintable(elemRelay.tagName()) << relay.mFlagRemote;
        } else if (0 == elemRelay.tagName().compare("smsOff", Qt::CaseInsensitive)) {  // for relay board
            relay.mSmsOff = elemRelay.text();
            qDebug() << "    " << qPrintable(elemRelay.tagName()) << relay.mSmsOff;
        } else if (0 == elemRelay.tagName().compare("smsOn", Qt::CaseInsensitive)) {  // for relay board
            relay.mSmsOn = elemRelay.text();
            qDebug() << "    " << qPrintable(elemRelay.tagName()) << relay.mSmsOn;
        }

        node = node.nextSibling();
    }

    relay.mStatus = RELAY_STATUS_UNKNOWN;

    board.mRelays.append(relay);
}
